package org.crud4j.wicket.markup.html.browse;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.wicket.Component;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.crud4j.core.BeforeRemoveException;
import org.crud4j.core.CrudBean;
import org.crud4j.core.CrudField;
import org.crud4j.core.CrudService;
import org.crud4j.wicket.CrudServiceInjectable;
import org.crud4j.wicket.markup.html.edit.EditModel;
import org.crud4j.wicket.markup.html.edit.EditPanel;

class BrowseRowsList extends ListView implements CrudServiceInjectable {

	private static final long serialVersionUID = 1L;

	private transient CrudService crudService;

	private IModel browseIModel;

	public BrowseRowsList(String id, IModel browseIModel, List<CrudBean> list) {
		super(id, list);
		setReuseItems(true);
		this.browseIModel = browseIModel;
	}

	private class EditForm extends Form {

		private static final long serialVersionUID = 1L;

		public EditForm(String id, IModel model) {
			super(id, model);
		}

		@Override
		protected void onSubmit() {
			// create edit model
			CrudBean bean = (CrudBean) this.getModel().getObject();
			IModel imodel = BrowseRowsList.this.browseIModel;
			EditModel editModel = new EditModel(bean, imodel);

			// replace component with edit component
			Component component = BrowseRowsList.this.getParent();
			component.replaceWith(new EditPanel(component.getId(), new Model(
					editModel)));
		}

	};

	private class DeleteForm extends Form {

		private static final long serialVersionUID = 1L;

		public DeleteForm(String id, IModel model) {
			super(id, model);
		}

		@SuppressWarnings("unchecked")
		@Override
		protected void onSubmit() {
			try {
				CrudBean bean = (CrudBean) this.getModel().getObject();
				crudService.remove(bean);
				// remove item from list
				List<CrudBean> list = (List<CrudBean>) BrowseRowsList.this
						.getModel().getObject();
				list.remove(bean);
			} catch (BeforeRemoveException e) {
				e.printStackTrace();
			}
		}

	};

	@Override
	protected void populateItem(ListItem item) {
		CrudBean bean = (CrudBean) item.getModelObject();

		// add columns
		Collection<CrudField> fields = bean.getBrowsableFields();
		if (List.class.isAssignableFrom(fields.getClass())) {
			item
					.add(new BrowseColumnsList("columns",
							(List<CrudField>) fields));
		} else {
			item.add(new BrowseColumnsList("columns", new ArrayList<CrudField>(
					fields)));
		}

		// add edit form
		item.add(new EditForm("editForm", item.getModel()));

		// add delete form
		item.add(new DeleteForm("deleteForm", item.getModel()));
	}

	public void setCrudService(CrudService crudService) {
		this.crudService = crudService;
	}
}
